'''
Contains the code to create a GUI application that allows a user to create
a new non-CSN claim.
'''
import os
import PySimpleGUI as sg
from dateparser import parse as dateparser_parse
from PyPDF2.utils import PdfReadError
from warranty_manager.claim.common import get_logger
from warranty_manager.gui.confirmation import get_confirmation
from warranty_manager.claim.hp.non_csn.blue_carpet_claim import BlueCarpetClaim
from warranty_manager.claim.hp.non_csn.blue_carpet_claim_creator_layout import LAYOUT
from warranty_manager.claim.hp.non_csn.get_serials import (
    create_template_file,
    get_serials,
    get_invoice_num,
    get_invoice_date,
    get_po_num,
)

CLAIM_INFO = {
    'invoice date': None,
    'invoice number': None,
    'po number': None,
    'product number': None,
    'quantity': 0,
    'invoice path': None,
    'serial path': None,
}

WINDOW = sg.Window('HP Blue Carpet Claim Creator', LAYOUT)

while True:
    event, values = WINDOW.read()

    if event in (None, 'Cancel'):
        break
    elif event == '-INVOICE_PATH-':
        if not os.path.isfile(values['-INVOICE_PATH-']):
            sg.popup_error('You must select an invoice!', title='Error')
            WINDOW['-INVOICE_PATH-'].update('')
            continue
        else:
            CLAIM_INFO['invoice path'] = values['-INVOICE_PATH-']

        # To clear all fields, when the invoice number changes
        WINDOW['-DATE-'].update('')
        WINDOW['-INVOICE_NUM-'].update('')
        WINDOW['-PO-'].update('')
        WINDOW['-PN-'].update('')
        WINDOW['-QUANTITY-'].update('')
        WINDOW['-SERIAL_PATH-'].update('')

        try:
            # To get all the non-serial number data from the current invoice
            CLAIM_INFO['invoice date'] = get_invoice_date(CLAIM_INFO['invoice path'])
            WINDOW['-DATE-'].update( CLAIM_INFO['invoice date'].strftime(r'%m/%d/%Y') )

            CLAIM_INFO['invoice number'] = get_invoice_num(CLAIM_INFO['invoice path'])
            WINDOW['-INVOICE_NUM-'].update(CLAIM_INFO['invoice number'])

            CLAIM_INFO['po number'] = get_po_num(CLAIM_INFO['invoice path'])
            WINDOW['-PO-'].update(CLAIM_INFO['po number'])
        except AttributeError: # Invoice data is not filled in
            WINDOW['-INVOICE_PATH-'].update('')
            continue
        except PdfReadError:
            sg.popup_error('You must select a valid PDF file for the invoice', title='Error')
            WINDOW['-INVOICE_PATH-'].update('')
            WINDOW['-DATE-'].update('')
            WINDOW['-INVOICE_NUM-'].update('')
            WINDOW['-PO-'].update('')
            continue
    elif event == 'Get Serials from Invoice':

        if get_confirmation('get the serial numbers from the invoice'):
            try:
                serials = get_serials(CLAIM_INFO['invoice path'])
            except TypeError:
                sg.popup_error('You must select an invoice!', title='Error')
                continue

            if serials:
                try:
                    WINDOW['-SERIAL_PATH-'].update(
                        create_template_file(
                            serials,
                            CLAIM_INFO['product number'],
                            CLAIM_INFO['invoice number'],
                            CLAIM_INFO['invoice path']
                        )
                    )
                except TypeError:
                    continue
                else:
                    quantity = len(serials)
                    WINDOW['-QUANTITY-'].update(quantity)

    elif event == 'Create Claim':
        # Invoice Path
        if not os.path.isfile(values['-INVOICE_PATH-']):
            sg.popup_error('You must select an invoice!', title='Error')
            WINDOW['-INVOICE_PATH-'].update('')
            continue
        else:
            CLAIM_INFO['invoice path'] = values['-INVOICE_PATH-']

        # Invoice Date
        if not dateparser_parse(values['-DATE-']):
            CLAIM_INFO['invoice date'] = get_invoice_date(CLAIM_INFO['invoice path'])
            WINDOW['-DATE-'].update( CLAIM_INFO['invoice date'].strftime(r'%m/%d/%Y') )
        else:
            CLAIM_INFO['invoice date'] = dateparser_parse(values['-DATE-'])

        # Invoice Number
        if not values['-INVOICE_NUM-'].strip():
            CLAIM_INFO['invoice number'] = get_invoice_num(CLAIM_INFO['invoice path'])
            WINDOW['-INVOICE_NUM-'].update(CLAIM_INFO['invoice number'])
        else:
            CLAIM_INFO['invoice number'] = values['-INVOICE_NUM-'].strip()

        # PO Number
        if not values['-PO-'].strip():
            CLAIM_INFO['po number'] = get_po_num(CLAIM_INFO['invoice path'])
            WINDOW['-PO-'].update(CLAIM_INFO['po number'])
        else:
            CLAIM_INFO['po number'] = values['-PO-'].strip()

        # Product Number
        if not values['-PN-'].strip():
            sg.popup_error('You must enter a product number!', title='Error')
            continue
        else:
            CLAIM_INFO['product number'] = values['-PN-'].strip()

        # Device Quantity
        try:
            quantity = int(values['-QUANTITY-'])
        except ValueError:
            sg.popup_error('You must enter the device quantity!', title='Error')
            continue
        else:
            CLAIM_INFO['quantity'] = quantity

        # Serial Path
        if not os.path.isfile(values['-SERIAL_PATH-']):
            sg.popup_error('You must select the serial number template!', title='Error')
            continue
        else:
            CLAIM_INFO['serial path'] = values['-SERIAL_PATH-']

        # To create the claim
        try:
            if get_confirmation('create a new, HP Blue Carpet claim'):
                CLAIM = BlueCarpetClaim(
                    {
                        'url': 'https://directory.id.hp.com/directory/v1/oauth/authorize'
                               '?response_type=code&client_id=z9kxOVDMmqUYJ7ReuYrz19b5As1zUCyQ'
                               '&redirect_uri=https://partner.hp.com/web/upp-apj/hpidlogin'
                               '&scope=openid+user.profile.read+user.profile.write+offline_access'
                               '&prompt=consent&locale=en-US&country=US&state=en_US',
                        **CLAIM_INFO,
                    }
                )
                CLAIM.create()

                # To clear all fields, after the claim has been successfully created
                WINDOW['-DATE-'].update('')
                WINDOW['-INVOICE_NUM-'].update('')
                WINDOW['-PO-'].update('')
                WINDOW['-PN-'].update('')
                WINDOW['-QUANTITY-'].update('')
                WINDOW['-INVOICE_PATH-'].update('')
                WINDOW['-SERIAL_PATH-'].update('')
        except CLAIM.get_network_exceptions():
            continue
        except Exception as err:
            sg.popup_error(
                'An unexpected error has occurred. '
                'Please check the logs for more information.',
                title='Error Message'
            )
            get_logger('blue_carpet_claim_creator').exception(err)
    else:
        continue
